package baiqitun.stupro.security.core.config;

import baiqitun.stupro.security.core.handler.OAuthLogoutHandler;
import baiqitun.stupro.security.core.handler.OAuthLogoutSuccessHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.expression.OAuth2WebSecurityExpressionHandler;
import org.springframework.security.web.authentication.logout.LogoutHandler;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;

/**
 * 资源服务器配置
 * @author kedaji
 */
@Configuration
@EnableResourceServer
public class ResourceServiceConfig extends ResourceServerConfigurerAdapter {
    @Autowired
    private OAuth2WebSecurityExpressionHandler oAuth2WebSecurityExpressionHandler;
    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                // 允许静态资源访问
                .antMatchers("*.ico", "*.js", "*.css", "*.png", "*.jpg").permitAll()
                // 允许Swagger 访问请求
                .antMatchers("/v2/api-docs",
                        "/swagger-resources/configuration/ui",
                        "/swagger-resources",
                        "/swagger-resources/configuration/security",
                        "/swagger-ui.html",
                        "/webjars/**"
                ).permitAll()
                .anyRequest().access("@userPermissionValidatorImpl.hasPermission(request, authentication)")
                // 注销时调用自定义的处理器处理注销请求
                .and().logout().logoutUrl("/logout").addLogoutHandler(logoutHandler()).logoutSuccessHandler(logoutSuccessHandler())
                .and().csrf().disable();
    }

    @Bean
    public OAuth2WebSecurityExpressionHandler oAuth2WebSecurityExpressionHandler(ApplicationContext applicationContext) {
        OAuth2WebSecurityExpressionHandler expressionHandler = new OAuth2WebSecurityExpressionHandler();
        expressionHandler.setApplicationContext(applicationContext);
        return expressionHandler;
    }

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources.expressionHandler(oAuth2WebSecurityExpressionHandler);
    }

    /**
     * 注入注销成功处理器
     * @return 自定义注销处理器
     */
    @Bean
    public LogoutSuccessHandler logoutSuccessHandler(){
        return new OAuthLogoutSuccessHandler();
    }

    /**
     * 注入自定义注销处理器
     * @return 自定义注销处理器
     */
    @Bean
    public LogoutHandler logoutHandler(){
        return new OAuthLogoutHandler();
    }
}
